package com.api.league.controller;

import com.api.core.annotation.PowerEnable;
import com.api.core.controller.Ctrl;
import com.api.core.response.Result;
import com.api.core.response.ResultCode;
import com.api.core.response.ResultGenerator;
import com.api.league.form.BatchAddFixturesForm;
import com.api.league.form.FixtureForm;
import com.api.league.service.LeagueMatchService;
import com.api.league.service.LeagueService;
import com.api.league.vo.LeagueFixtureVo;
import com.api.league.vo.LeagueMatchDayVo;
import com.api.league.vo.LeagueStandingVo;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotNull;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author RenQiang
 * @date 2021/5/30
 */
@Slf4j
@PowerEnable(name = "联赛比赛", url = "/league/match")
@Api(value = "联赛比赛", tags = {LeagueMatchController.API_TAG})
@RestController
@RequestMapping("/league/match")
@Validated
public class LeagueMatchController extends Ctrl {
    public static final String API_TAG = "联赛比赛";

    private final LeagueMatchService leagueMatchService;
    private final LeagueService leagueService;

    public LeagueMatchController(LeagueMatchService leagueMatchService, LeagueService leagueService) {
        this.leagueMatchService = leagueMatchService;
        this.leagueService = leagueService;
    }

    @ApiOperation(value = "批量添加对局", tags = {API_TAG}, notes = "批量添加对局")
    @PostMapping("/add-fixture-batch")
    public Result batchAddFixtures(@Validated @RequestBody BatchAddFixturesForm form) {
        Set<Integer> matchDayNos = form.getMatchDays().stream()
                .map(BatchAddFixturesForm.MatchDayForm::getNo)
                .collect(Collectors.toSet());
        if (matchDayNos.size() != form.getMatchDays().size()) {
            return ResultGenerator.genFailResult(ResultCode.FAIL.code(), "The serial number of the match day cannot be repeated");
        }

        try {
            leagueMatchService.batchAddFixtures(form);
        } catch (IllegalArgumentException e) {
            log.error("批量添加对局失败", e);
            return ResultGenerator.genFailResult(ResultCode.FAIL.code(), e.getMessage());
        }
        return ResultGenerator.genSuccessResult();
    }

    @ApiOperation(value = "批量修改对局", tags = {API_TAG}, notes = "批量修改对局")
    @PostMapping("/update-fixture-batch")
    public Result batchUpdateFixtures(@Validated @RequestBody List<FixtureForm> fixtureForms) {
        if (fixtureForms.stream()
                .anyMatch(fixture -> fixture.getFixtureId() == null)) {
            return ResultGenerator.genFailResult(ResultCode.FAIL.code(), "Match ID cannot be empty");
        }
        try {
            leagueMatchService.batchUpdateFixtures(fixtureForms);
        } catch (IllegalArgumentException e) {
            log.error("批量修改对局失败", e);
            return ResultGenerator.genFailResult(ResultCode.FAIL.code(), e.getMessage());
        }
        return ResultGenerator.genSuccessResult();
    }

    @ApiOperation(value = "删除对局", tags = {API_TAG}, notes = "删除对局")
    @PostMapping("/delete-fixture")
    public Result deleteFixture(@ApiParam(value = "对局ID") @RequestParam Long fixtureId) {
        try {
            leagueMatchService.deleteFixtureById(fixtureId);
        } catch (IllegalArgumentException e) {
            log.error("删除对局失败", e);
            return ResultGenerator.genFailResult(ResultCode.FAIL.code(), e.getMessage());
        }
        return ResultGenerator.genDeleteSuccessResult();
    }

    @ApiOperation(value = "删除比赛日", tags = {API_TAG}, notes = "删除比赛日，同时删除比赛日下的所有对局")
    @PostMapping("/delete-match-day")
    public Result deleteMatchDay(@ApiParam(value = "比赛日ID") @RequestParam Long matchDayId) {
        try {
            leagueMatchService.deleteMatchDayById(matchDayId);
        } catch (IllegalArgumentException e) {
            log.error("删除比赛日失败", e);
            return ResultGenerator.genFailResult(ResultCode.FAIL.code(), e.getMessage());
        }
        return ResultGenerator.genDeleteSuccessResult();
    }

    @ApiOperation(value = "分页查询比赛日", tags = {API_TAG}, notes = "分页查询比赛日")
    @GetMapping("/find-match-day-page")
    public Result findMatchDayByPage(@ApiParam(value = "联赛ID") @RequestParam Long leagueId,
                                     @ApiParam(value = "页号") @RequestParam(defaultValue = "1") Integer page,
                                     @ApiParam(value = "分页大小") @RequestParam(defaultValue = "10") Integer size) {
        PageInfo<LeagueMatchDayVo> pageInfo = leagueMatchService.findMatchDayByPage(leagueId, page, size);
        return ResultGenerator.genSuccessResult(pageInfo);
    }

    @ApiOperation(value = "分页查询对局", tags = {API_TAG}, notes = "分页查询对局")
    @GetMapping("/find-fixture-page")
    public Result findFixtureByPage(@ApiParam(value = "联赛ID") @RequestParam Long leagueId,
                                    @ApiParam(value = "页号") @RequestParam(defaultValue = "1") Integer page,
                                    @ApiParam(value = "分页大小") @RequestParam(defaultValue = "10") Integer size) {
        PageInfo<LeagueFixtureVo> pageInfo = leagueMatchService.findFixtureByPage(leagueId, page, size);
        return ResultGenerator.genSuccessResult(pageInfo);
    }

    @ApiOperation(value = "保存对局结果", tags = {API_TAG}, notes = "保存对局结果")
    @PostMapping("/save-fixture-result")
    public Result saveFixtureResult(@ApiParam(value = "对局ID") @RequestParam Long fixtureId,
                                    @ApiParam(value = "战队1分数") @RequestParam @NotNull Integer team1Score,
                                    @ApiParam(value = "战队2分数") @RequestParam @NotNull Integer team2Score) {

        try {
            leagueMatchService.saveFixtureResultAndSettle(fixtureId, team1Score, team2Score);
        } catch (IllegalArgumentException e) {
            log.error("保存对局结果失败", e);
            return ResultGenerator.genFailResult(ResultCode.FAIL.code(), e.getMessage());
        }
        return ResultGenerator.genSuccessResult();
    }

    @ApiOperation(value = "分页查询比赛日战绩排名", tags = {API_TAG}, notes = "分页查询比赛日战绩排名")
    @GetMapping("/find-match-day-standing-page")
    public Result findMatchDayStandingByPage(@ApiParam(value = "联赛ID") @RequestParam Long leagueId,
                                             @ApiParam(value = "起始日期") @RequestParam(required = false) Date beginDate,
                                             @ApiParam(value = "截止日期") @RequestParam(required = false) Date endDate,
                                             @ApiParam(value = "页号") @RequestParam(defaultValue = "1") Integer page,
                                             @ApiParam(value = "分页大小") @RequestParam(defaultValue = "10") Integer size) {
        PageInfo<LeagueStandingVo> pageInfo = leagueMatchService.findMatchDayStandingByPage(leagueId, beginDate, endDate, page, size);
        return ResultGenerator.genSuccessResult(pageInfo);
    }

    @ApiOperation(value = "分页查询战队战绩排名", tags = {API_TAG}, notes = "分页查询战队战绩排名")
    @GetMapping("/find-team-standing-page")
    public Result findTeamStandingByPage(@ApiParam(value = "联赛ID") @RequestParam Long leagueId,
                                         @ApiParam(value = "页号") @RequestParam(defaultValue = "1") Integer page,
                                         @ApiParam(value = "分页大小") @RequestParam(defaultValue = "10") Integer size) {
        PageInfo<LeagueStandingVo> pageInfo = leagueMatchService.findTeamStandingByPage(leagueId, page, size);
        return ResultGenerator.genSuccessResult(pageInfo);
    }
}
